class PromiseUtils {

    /**
     * 返回响应结果的数据
     */
    public static resolve() {
        return Promise.resolve();
    }

    /**
     * 返回响应结果的数据
     */
    public static resolveValue<T>(data: T) {
        return Promise.resolve(data);
    }

    /**
     * 返回响应结果的错误信息
     *
     * @param errorMsg 错误信息
     */
    public static reject(errorMsg: string | null) {
        return Promise.reject(errorMsg);
    }

    /**
     * 返回系统错误的错误信息
     */
    public static rejectSystemError() {
        return Promise.reject("系统繁忙, 请稍后再尝试吧!");
    }

    /**
     * 延迟指定时间后返回一个 Promise
     *
     * @param ms 延迟的毫秒数
     * @returns 一个延迟后的 Promise
     */
    public static delay(ms: number): Promise<void> {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }

    /**
     * 重试一个异步函数，直到成功或达到最大重试次数
     *
     * @param fn 需要重试的异步函数
     * @param retries 最大重试次数，默认 3 次
     * @param delayMs 每次重试之间的延迟时间，默认 1000 毫秒
     * @returns Promise<T> 返回异步函数的结果
     */
    public static async retry<T>(fn: () => Promise<T>, retries: number = 3, delayMs: number = 1000): Promise<T> {
        try {
            return await fn();
        } catch (error) {
            if (retries <= 0) throw error;
            await PromiseUtils.delay(delayMs);
            return PromiseUtils.retry(fn, retries - 1, delayMs);
        }
    }

    /**
     * 为 Promise 设置超时时间（用于网络超时）
     *
     * @param promise 需要设置超时的 Promise
     * @param timeoutMs 超时时间（毫秒）
     * @returns Promise<T> 返回 Promise 的结果，如果超时则抛出错误
     */
    public static timeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {
        return new Promise((resolve, reject) => {
            const timeoutId = setTimeout(() => {
                reject(new Error(`Promise timed out after ${timeoutMs} ms`));
            }, timeoutMs);

            promise.then((result) => {
                clearTimeout(timeoutId);
                resolve(result);
            }).catch((error) => {
                clearTimeout(timeoutId);
                reject(error);
            });
        });
    }
}

export default PromiseUtils;
